{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### The Box widgets\n",
    "\n",
    "+ Box\n",
    "+ FlexBox\n",
    "+ Accordion\n",
    "+ TabWidget"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "These widgets are used to provide a layout for placing other widgets."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "{-# LANGUAGE OverloadedStrings #-}\n",
    "import IHaskell.Display.Widgets\n",
    "import Data.Text as T (pack)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "These widgets have a `Children` field, which accepts a `[ChildWidget]`. A `ChildWidget` can be created using the `ChildWidget` constructor."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<style>/* Styles used for the Hoogle display in the pager */\n",
       ".hoogle-doc {\n",
       "display: block;\n",
       "padding-bottom: 1.3em;\n",
       "padding-left: 0.4em;\n",
       "}\n",
       ".hoogle-code {\n",
       "display: block;\n",
       "font-family: monospace;\n",
       "white-space: pre;\n",
       "}\n",
       ".hoogle-text {\n",
       "display: block;\n",
       "}\n",
       ".hoogle-name {\n",
       "color: green;\n",
       "font-weight: bold;\n",
       "}\n",
       ".hoogle-head {\n",
       "font-weight: bold;\n",
       "}\n",
       ".hoogle-sub {\n",
       "display: block;\n",
       "margin-left: 0.4em;\n",
       "}\n",
       ".hoogle-package {\n",
       "font-weight: bold;\n",
       "font-style: italic;\n",
       "}\n",
       ".hoogle-module {\n",
       "font-weight: bold;\n",
       "}\n",
       ".hoogle-class {\n",
       "font-weight: bold;\n",
       "}\n",
       "\n",
       ".get-type {\n",
       "color: green;\n",
       "font-weight: bold;\n",
       "font-family: monospace;\n",
       "display: block;\n",
       "white-space: pre-wrap;\n",
       "}\n",
       ".show-type {\n",
       "color: green;\n",
       "font-weight: bold;\n",
       "font-family: monospace;\n",
       "margin-left: 1em;\n",
       "}\n",
       ".mono {\n",
       "font-family: monospace;\n",
       "display: block;\n",
       "}\n",
       ".err-msg {\n",
       "color: red;\n",
       "font-style: italic;\n",
       "font-family: monospace;\n",
       "white-space: pre;\n",
       "display: block;\n",
       "}\n",
       "#unshowable {\n",
       "color: red;\n",
       "font-weight: bold;\n",
       "}\n",
       ".err-msg.in.collapse {\n",
       "padding-top: 0.7em;\n",
       "}\n",
       "\n",
       ".highlight-code {\n",
       "white-space: pre;\n",
       "font-family: monospace;\n",
       "}\n",
       "\n",
       ".suggestion-warning { \n",
       "font-weight: bold;\n",
       "color: rgb(200, 130, 0);\n",
       "}\n",
       ".suggestion-error { \n",
       "font-weight: bold;\n",
       "color: red;\n",
       "}\n",
       ".suggestion-name {\n",
       "font-weight: bold;\n",
       "}\n",
       "\n",
       "</style><span class='get-type'>ChildWidget :: forall w. RecAll Attr (WidgetFields w) ToPairs => IPythonWidget w -> ChildWidget</span>"
      ],
      "text/plain": [
       "ChildWidget :: forall w. RecAll Attr (WidgetFields w) ToPairs => IPythonWidget w -> ChildWidget"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    ":t ChildWidget"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### `Box`, `VBox`, `HBox` and `GridBox`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": []
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "-- Create new Boxes and GridBox\n",
    "box <- mkBox\n",
    "vbox <- mkVBox\n",
    "hbox <- mkHBox\n",
    "gbox <- mkGridBox"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`Box` and `HBox` have a horizontal orientation. This means that adding new widgets to them lays them out horizontally. In contrast, `VBox` lays them vertically. `GridBox` lets you display the widgets in a grid. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "b283b563-7997-4306-b009-c05ceb7f704e",
       "version_major": 2,
       "version_minor": 0
      }
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "559f7696-9ac2-4358-94f8-26d22f2814dc",
       "version_major": 2,
       "version_minor": 0
      }
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "721db87f-08e1-4e1f-8b21-6a6253a9efed",
       "version_major": 2,
       "version_minor": 0
      }
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "9ac8056c-676a-4bee-9ef1-61d012ab7d92",
       "version_major": 2,
       "version_minor": 0
      }
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import Control.Monad (replicateM, mapM_)\n",
    "\n",
    "-- Make some buttons\n",
    "buttons <- replicateM 4 mkButton\n",
    "\n",
    "-- We put its index as description\n",
    "mapM_ (\\(w,i)-> setField @Description w $ T.pack $ \"Test \" ++ show i) $ zip buttons [1..]\n",
    "\n",
    "-- Add children widgets to boxes\n",
    "let children = map ChildWidget buttons\n",
    "setField @Children box children\n",
    "setField @Children hbox children\n",
    "setField @Children vbox children\n",
    "setField @Children gbox children\n",
    "\n",
    "setField @BoxStyle box SuccessBox\n",
    "setField @BoxStyle vbox InfoBox\n",
    "setField @BoxStyle hbox WarningBox\n",
    "setField @BoxStyle gbox DangerBox\n",
    "\n",
    "-- Display boxes\n",
    "box\n",
    "vbox\n",
    "hbox\n",
    "gbox"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You might be thinking that there is no difference between `VBox` and `GridBox`, but that's not true.\n",
    "\n",
    "`VBox` has always one column, while `GridBox` lets you modify the number of colums if you modify its css.\n",
    "\n",
    "Let's make a 2x2 grid on `GridBox`. To accomplish our goal, we need to obtain it's associated `Layout` and modify its `GridTemplateColumns` field.\n",
    "\n",
    "> You can get a complete and updated CSS grid layout reference at [Mozilla's docs](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "import qualified IHaskell.Display.Widgets.Layout as L\n",
    "\n",
    "layout <- getField @Layout gbox\n",
    "setField @L.GridTemplateColumns layout $ Just \"repeat(2,1fr)\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### `Accordion` and `TabWidget`"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "These widgets are useful for displaying a variety of content in a small amount of space."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "acc <- mkAccordion\n",
    "tab <- mkTab"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's add some children and see what the result looks like."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "68e855e5-4a69-4a8f-a9d4-b354e9d78ea5",
       "version_major": 2,
       "version_minor": 0
      }
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "82cda4f9-ddb0-475e-b645-4bc4ead4c522",
       "version_major": 2,
       "version_minor": 0
      }
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "buttons' <- replicateM 5 mkButton\n",
    "\n",
    "let children = map ChildWidget buttons'\n",
    "\n",
    "setField @Titles acc $ map (\\x->T.pack $ \"Button \" ++ show x) [1..5]\n",
    "getField @Titles acc >>= setField @Titles tab\n",
    "setField @Children acc children \n",
    "setField @Children tab children\n",
    "\n",
    "acc\n",
    "tab"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Both the widgets are similar, the only major difference is in the orientation. `Accordion` is vertical, whereas `TabWidget` is horizontal. We can get or set the selected tab with the field `SelectedIndex :: Maybe Integer`. If it's set to `Nothing`, then the accordion/tabs are all closed."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Nothing"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "Nothing"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "getField @SelectedIndex acc\n",
    "getField @SelectedIndex tab\n",
    "\n",
    "-- Let's try closing them\n",
    "setField @SelectedIndex tab Nothing\n",
    "setField @SelectedIndex acc Nothing"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Haskell",
   "language": "haskell",
   "name": "haskell"
  },
  "language_info": {
   "codemirror_mode": "ihaskell",
   "file_extension": ".hs",
   "mimetype": "text/x-haskell",
   "name": "haskell",
   "pygments_lexer": "Haskell",
   "version": "9.8.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
